/******************************************************************************
 * FileName:    gwin_general_timer.c
 * Desc:        通用定时器
 *                  循环判断的定时器
 *
 * Author:      Lin
 * Notes:
 *
 ******************************************************************************/

/*-------------------------- Includes ---------------------------------------*/
#include "string.h"
#include "gwin_general_clock.h"
#include "gwin_general_timer.h"


/*-------------------------- Macro Definitions ------------------------------*/
#ifndef NULL
#define NULL                            ((void *)0)
#endif


/*-------------------------- Type Declarations ------------------------------*/

/*-------------------------- Global Variables -------------------------------*/

/*-------------------------- Local Variables --------------------------------*/
static uint8_t gwin_general_timer_ctrl_map_cnt = 0;
static gwin_general_timer_ctrl_t gwin_general_timer_ctrl_map[GWIN_GENERAL_TIMER_CNT_MAX] = { [0 ... GWIN_GENERAL_TIMER_CNT_MAX - 1] = { 0x00 } };


/*-------------------------- Functions Declarations -------------------------*/

/*-------------------------- Functions Definitions --------------------------*/
/**
 * @brief 创建
 */
gwin_general_timer_ctrl_t *gwin_general_timer_create(const char *name, uint32_t period_time, uint8_t repeat, void *arg, void (*callback)(void *arg))
{
    gwin_general_timer_ctrl_t *new = NULL;

    if (gwin_general_timer_ctrl_map_cnt < GWIN_GENERAL_TIMER_CNT_MAX)
    {
        new = &gwin_general_timer_ctrl_map[gwin_general_timer_ctrl_map_cnt];
        new->used = 1;
        new->start_time = 0;
//        new->name = name;
        new->period_time = period_time;
        new->repeat = repeat;
//        new->arg = arg;
        new->callback = callback;
        gwin_general_timer_ctrl_map_cnt++;
    }

    return new;
}

/**
 * @brief 开始
 */
uint8_t gwin_general_timer_start(gwin_general_timer_ctrl_t *timer)
{
    uint8_t ret = 0;

    if (timer->used)
    {
        ret = 1;
        gwin_save_general_clock(&timer->start_time);
    }

    return ret;
}

/**
 * @brief 停止
 */
uint8_t gwin_general_timer_stop(gwin_general_timer_ctrl_t *timer)
{
    uint8_t ret = 0;

    if (timer->used)
    {
        ret = 1;
        gwin_clear_general_clock(&timer->start_time);
    }

    return ret;
}

/**
 * @brief 删除
 */
uint8_t gwin_general_timer_delete(gwin_general_timer_ctrl_t *timer)
{
    uint8_t ret = 0;

    if (timer->used)
    {
        for (uint8_t i = 0; i < gwin_general_timer_ctrl_map_cnt; i++)
        {
            if (timer == &gwin_general_timer_ctrl_map[i])
            {
                ret = 1;
                memcpy(&gwin_general_timer_ctrl_map[i], &gwin_general_timer_ctrl_map[i + 1], gwin_general_timer_ctrl_map_cnt - 1 - i);
                memset(&gwin_general_timer_ctrl_map[gwin_general_timer_ctrl_map_cnt - 1], 0x00, sizeof(gwin_general_timer_ctrl_t));
                gwin_general_timer_ctrl_map_cnt--;
                break;
            }
        }
    }

    return ret;
}

/**
 * @brief 停止
 */
uint8_t gwin_general_timer_is_active(gwin_general_timer_ctrl_t *timer)
{
    uint8_t ret = 0;

    if (timer->used && gwin_get_general_clock_is_start(&timer->start_time))
    {
        ret = 1;
    }

    return ret;
}



/**
 * @brief 循环判断的定时器
 */
void gwin_general_timer_handle(void)
{
    for (uint8_t i = 0; i < gwin_general_timer_ctrl_map_cnt; i++)
    {
        if (gwin_general_timer_ctrl_map[i].used)
        {
            if (gwin_pass_general_clock(gwin_general_timer_ctrl_map[i].start_time, gwin_general_timer_ctrl_map[i].period_time))
            {
                if (gwin_general_timer_ctrl_map[i].repeat)
                {
                    gwin_save_general_clock(&gwin_general_timer_ctrl_map[i].start_time);
                }
                else
                {
                    gwin_clear_general_clock(&gwin_general_timer_ctrl_map[i].start_time);
                }

                if (gwin_general_timer_ctrl_map[i].callback != NULL)
                {
                    gwin_general_timer_ctrl_map[i].callback(NULL);//(gwin_general_timer_ctrl_map[i].arg);
                }
            }
        }
    }
}


/*-------------------------- END OF FILE ------------------------------------*/

